package jinyilw.swing.visuals.Jcomp;

import jinyilw.swing.ComponentTools;
import jinyilw.swing.FontTools;
import jinyilw.swing.icon.LazyScaleIcon;
import jinyilw.swing.rlaf.theme.RThemeColor;

import javax.swing.SwingConstants;
import javax.swing.plaf.UIResource;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Insets;
import java.io.File;
import java.net.URL;
import java.util.Objects;

public class JImageTextComp extends IJMouseActComp implements SwingConstants
{
	private static final long serialVersionUID = -1845452526101489886L;
	protected LazyScaleIcon lrImage;
	protected String text;
	private Image image;
	protected Font font = FontTools.defaultFont;
	private int gap = 5;
	private int imageLocation = WEST;
	private int horizontalAlignment = CENTER;
	protected int hy;
	protected int textW, textH, imageW, imageH;
	protected int minimumW, minimumH;

	public JImageTextComp()
	{
	}

	public JImageTextComp(String text)
	{
		setText(text);
	}

	public JImageTextComp(File imageFile, String text)
	{
		setImageFile(imageFile);
		setText(text);
	}

	public void setImageURL(URL url)
	{
		setImage(LazyScaleIcon.getIcon(url));
	}

	public void setImageFile(File file)
	{
		setImage(LazyScaleIcon.getIcon(file));
	}

	public void setImage(LazyScaleIcon lrImage)
	{
		if (this.lrImage == lrImage)
			return;
		this.lrImage = lrImage;
		if (isShowing())
			repaint();
	}

	@Override
	public void updateText(String text)
	{
		setText(text);
	}

	public void setText(String text)
	{
		if (Objects.equals(text, this.text))
			return;
		this.text = text;
		updateTSize();
	}

	public String getText()
	{
		return text;
	}

	@Override
	public void setFont(Font font)
	{
		if (font == null || font.equals(this.font))
			return;
		this.font = font;
		updateTSize();
	}

	@Override
	public Font getFont()
	{
		if (font != null)
			return font;
		return super.getFont();
	}

	@Override
	public Dimension getPreferredSize()
	{
		if (text != null && !isPreferredSizeSet())
		{
			if (minimumW == 0)
				calculatePaints();
			Insets insets = getInsets();
			return new Dimension(minimumW + insets.left + insets.right,
					minimumH + insets.top + insets.bottom);
		}
		return super.getPreferredSize();
	}

	public void setImageLocation(int imageLocation)
	{
		this.imageLocation = imageLocation;
		if (isShowing())
			repaint();
	}

	public void setHorizontalAlignment(int horizontalAlignment)
	{
		this.horizontalAlignment = horizontalAlignment;
		if (isShowing())
			repaint();
	}

	public void setGap(int gap)
	{
		this.gap = gap;
		if (isShowing())
			repaint();
	}

	protected void updateTSize()
	{
		if (text != null && font != null)
		{
			FontMetrics fm = getFontMetrics(font);
			hy = fm.getAscent();
			textW = fm.stringWidth(text);
			textH = fm.getHeight();
		} else
			textW = textH = 0;

		if (isShowing())
			repaint();
	}

	private int tX, tY, iX, iY;

	private void calculatePaints()
	{
		Insets insets = getInsets();
		int w = getWidth() - insets.left - insets.right;
		int h = getHeight() - insets.top - insets.bottom;
		iX = insets.left;
		iY = insets.top;
		tX = insets.left;
		tY = insets.top + hy;
		image = lrImage != null ? lrImage.getImage() : null;
		if (image != null)
		{
			imageW = lrImage.getIconWidth();
			imageH = lrImage.getIconHeight();
			switch (imageLocation)
			{
				case WEST:
				case EAST:
					minimumW = textW + gap + imageW;
					minimumH = Math.max(textH, imageH);
					iY += (h - imageH) / 2;
					tY += (h - textH) / 2;
					if (imageLocation == WEST)
						tX += imageW + gap;
					else
						iX += textW + gap;
					break;
				case NORTH:
				case SOUTH:
					boolean bool = textW > imageW;
					minimumW = bool ? textW : imageW;
					minimumH = textH + gap + imageH;
					if (bool)
						iX += (minimumW - imageW) / 2;
					else
						tX += (minimumW - textW) / 2;
					if (imageLocation == NORTH)
					{
						iY += (h - minimumH) / 2;
						tY = iY + imageH + gap;
					} else
					{
						tY += (h - minimumH) / 2;
						iY = tY + textH + gap;
					}
			}
		} else
		{
			minimumW = textW;
			minimumH = textH;
			tY += (h - textH) / 2;
		}
		if (horizontalAlignment == CENTER)
		{
			int offX = (w - minimumW) / 2;
			tX += offX;
			iX += offX;
		} else if (horizontalAlignment == RIGHT)
		{
			int offX = w - minimumW;
			tX += offX;
			iX += offX;
		}
	}

	protected void drawText(Graphics2D g2d, Color color)
	{
		g2d.setColor(color);
		g2d.drawString(text, tX, tY);
	}

	@Override
	protected void paintComponent(Graphics g)
	{
		calculatePaints();
		Graphics2D g2d = (Graphics2D) g;
		Composite composite = ComponentTools.applyEnableAlpha(g2d, isEnabled(),
				1f, 0.3f);
		if (image != null)
			g2d.drawImage(image, iX, iY, imageW, imageH, null);

		if (text == null || text.isEmpty() || font == null)
		{
			if (composite != null)
				g2d.setComposite(composite);
			return;
		}
		renderingConfig.setTextAADrawing(g2d);
		g2d.setFont(font);
		Color fColor = getForeground();
		if (fColor == null || fColor instanceof UIResource)
			fColor = RThemeColor.colorSet.textColor;
		drawText(g2d, fColor);
		renderingConfig.resetTextAADrawing(g2d);
		if (composite != null)
			g2d.setComposite(composite);
	}

}
